package logger

import (
	"math/rand"
	"time"
)

// 网络模拟器，模拟广域网环境
type NetworkSimulator struct {
	nodeID       uint64
	totalNodes   int
	baseDelay    time.Duration
	jitter       time.Duration
	packetLoss   float64
	bandwidth    int64 // Mbps
}

func NewNetworkSimulator(nodeID, totalNodes int) *NetworkSimulator {
	// 根据节点数量调整网络参数
	var baseDelay time.Duration
	var jitter time.Duration
	var packetLoss float64
	var bandwidth int64
	
	switch totalNodes {
	case 4:
		baseDelay = 20 * time.Millisecond
		jitter = 10 * time.Millisecond
		packetLoss = 0.001 // 0.1%
		bandwidth = 1000 // 1 Gbps
	case 9:
		baseDelay = 50 * time.Millisecond
		jitter = 25 * time.Millisecond
		packetLoss = 0.005 // 0.5%
		bandwidth = 500 // 500 Mbps
	case 17:
		baseDelay = 100 * time.Millisecond
		jitter = 50 * time.Millisecond
		packetLoss = 0.01 // 1%
		bandwidth = 200 // 200 Mbps
	default:
		baseDelay = 30 * time.Millisecond
		jitter = 15 * time.Millisecond
		packetLoss = 0.002
		bandwidth = 800
	}
	
	return &NetworkSimulator{
		nodeID:     uint64(nodeID),
		totalNodes: totalNodes,
		baseDelay:  baseDelay,
		jitter:     jitter,
		packetLoss: packetLoss,
		bandwidth:  bandwidth,
	}
}

func (ns *NetworkSimulator) SimulateNetworkDelay() time.Duration {
	// 模拟网络延迟
	delay := ns.baseDelay + time.Duration(rand.Int63n(int64(ns.jitter)))
	
	// 模拟包丢失
	if rand.Float64() < ns.packetLoss {
		// 包丢失，返回重传延迟
		return delay * 3
	}
	
	return delay
}

func (ns *NetworkSimulator) SimulateBandwidthLimit(dataSize int64) time.Duration {
	// 模拟带宽限制
	// 计算传输时间 (字节转换为位，然后除以带宽)
	bits := dataSize * 8
	transmissionTime := time.Duration(bits*1000/ns.bandwidth) * time.Millisecond
	
	// 添加网络延迟
	networkDelay := ns.SimulateNetworkDelay()
	
	return networkDelay + transmissionTime
}

func (ns *NetworkSimulator) GetNetworkStats() map[string]interface{} {
	return map[string]interface{}{
		"node_id":      ns.nodeID,
		"total_nodes":  ns.totalNodes,
		"base_delay":   ns.baseDelay.Milliseconds(),
		"jitter":       ns.jitter.Milliseconds(),
		"packet_loss":  ns.packetLoss,
		"bandwidth":    ns.bandwidth,
	}
}
